package cn.funnymap.lgis.tools.vector.parser;

import cn.funnymap.lgis.tools.exception.ShpParserRuntimeException;
import cn.funnymap.lgis.tools.vector.util.WKTUtil;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.geometry.jts.WKTWriter2;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryFactory;
import org.opengis.feature.simple.SimpleFeature;

import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Shapefile-WKT字符串解析器
 *
 * @author jiaoxn
 */
public class Shp2WktParser extends ShpParser<List<String>> {
    public Shp2WktParser(ShpParseParameter parseParameter) {
        super(parseParameter);
    }

    @Override
    public List<String> parseShapefile() {
        List<String> wktList = new ArrayList<>();

        try {
            for(Path path : processorParameter.getShpFilePathList()) {
                SimpleFeatureCollection featureCollection = this.readAndTransform(path);
                List<Geometry> geometryList = this.readGeometry(featureCollection);
                String wkt = this.geometry2Wkt(geometryList);
                wktList.add(wkt);
            }
        } catch (IOException ioException) {
            throw new ShpParserRuntimeException("Shapefile解析失败，" + ioException.getCause());
        } finally {
            this.deleteRelatedFile();
        }

        return wktList;
    }
    private List<Geometry> readGeometry(SimpleFeatureCollection simpleFeatureCollection) {
        return Arrays.stream(simpleFeatureCollection.toArray())
                .map(item -> (Geometry) ((SimpleFeature) item).getDefaultGeometry())
                .collect(Collectors.toList());
    }
    private String geometry2Wkt(List<Geometry> geometryList) {
        GeometryFactory geometryFactory = new GeometryFactory();
        GeometryCollection geometryCollection =
                geometryFactory.createGeometryCollection(geometryList.toArray(new Geometry[0]));

        List<String> wktList = new ArrayList<>();
        WKTWriter2 wktWriter2 = new WKTWriter2();
        for (int i = 0; i < geometryCollection.getNumGeometries(); i++) {
            Geometry geometry = geometryCollection.getGeometryN(i);
            wktList.add(wktWriter2.write(geometry));
        }

        return WKTUtil.asOne(wktList);
    }
}
